//
// Created by zhengjuping on 24-8-16.
//

#include <esp_log.h>
#include <driver/i2c.h>
#include <cstring>
#include "include/SensorManager.h"
#include "sdkconfig.h"

#define TAG  "SensorManager"

SensorManager::SensorManager(): _isRunning(false) {

    i2c_config_t conf;
    memset(&conf, 0, sizeof(i2c_config_t));

    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = CONFIG_ENVII_SDA;
    conf.scl_io_num = CONFIG_ENVII_SCL;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = 400000;
    i2c_param_config((i2c_port_t)0, &conf);
    i2c_driver_install((i2c_port_t)0, conf.mode, 0, 0, 0);

    _bmp280 = std::make_unique<BMP280>();
    _sht30 = std::make_unique<SHT30>();
}

SensorManager::~SensorManager() {
    i2c_driver_delete((i2c_port_t)0);
}


void SensorManager::registerObserver(ISensorObserver *observer) {
    _observers.push_back(observer);
}

void SensorManager::unregisterObserver(ISensorObserver *observer) {
    _observers.remove(observer);
}

void SensorManager::notifyObservers(float temperature,
                                    float humidity,
                                    float pressure) {
    for (auto observer : _observers) {
        observer->onSensorValueUpdata(temperature, humidity, pressure);
    }
}

int32_t SensorManager::start(std::chrono::milliseconds interval) {
    if( _isRunning ){
        ESP_LOGE( TAG, "SensorManager is already running");
        return -1;
    }
    _isRunning = true;
    _sensorCaptureThread = std::thread([this, interval]() {
        float bmp280_temperature = 0, sht30_temperature = 0,avg_temperature = 0;
        float humidity = 0;
        float pressure = 0;
        for( int32_t i = 0; i < 3; i++ ){
            _bmp280->getValue(pressure, bmp280_temperature);
            _sht30->getValue(sht30_temperature, humidity);
        }
        while (_isRunning) {
            _bmp280->getValue(pressure, bmp280_temperature);
            _sht30->getValue(sht30_temperature, humidity);
            avg_temperature = (bmp280_temperature + sht30_temperature) / 2;
            notifyObservers(avg_temperature, humidity, pressure);
            std::this_thread::sleep_for(interval);
        }
    });
    return 0;
}

int32_t SensorManager::stop() {
    if( !_isRunning ){
        ESP_LOGE( TAG, "SensorManager is not running");
        return -1;
    }

    _isRunning = false;
    _sensorCaptureThread.join();
    return 0;
}


